package com.easy.deploy.util;



import com.easy.deploy.vo.DeployPath;
import com.easy.util.DESUtil;
import com.jcraft.jsch.*;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.common.IOUtils;
import net.schmizz.sshj.connection.channel.direct.Session;
import net.schmizz.sshj.transport.verification.PromiscuousVerifier;

import java.io.*;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * @author tanyongpeng
 * <p>des</p>
 **/
public class SftpUtil {

    public static Set<String> exec(String host, int port, String username, String password, String e,Set<String> resultArray) throws IOException {
        final SSHClient ssh = new SSHClient();
        ssh.addHostKeyVerifier(new PromiscuousVerifier());
        ssh.connect(host, port);
        InputStream inputStream = null;
        OutputStream output = null;
        ssh.authPassword(username, DESUtil.decrypt(password));
        try (Session session = ssh.startSession()) {
            final Session.Command cmd = session.exec(e);
            inputStream = cmd.getInputStream();
            output = IOUtils.readFully(inputStream);
            if (!output.toString().trim().equals("")){
                return CharUtil.getProcessNumber(output.toString(),resultArray);
            }else {
                return resultArray;
            }
        }catch (Exception e1){
            return resultArray;
        }finally {
            // 处理异常
            ssh.disconnect();
            if (inputStream != null){
                inputStream.close();
            }
            if (output != null){
                output.close();
            }
        }
    }

    /**
     * 执行命令
     * @param e
     */
    public static void exec(String host, int port, String username, String password, String e) throws IOException {
        final SSHClient ssh = new SSHClient();
        ssh.addHostKeyVerifier(new PromiscuousVerifier());
        ssh.connect(host, port);
        ssh.authPassword(username, DESUtil.decrypt(password));
        try (Session session = ssh.startSession()) {
            session.exec(e);
        }catch (Exception ex){
            System.out.println(ex.getMessage());
        }finally {
            // 处理异常
            ssh.disconnect();
        }
    }

    public static void delete(String host,int port,String username,String password,String servicePath,String fileName){
        ChannelSftp sftp = null;
        com.jcraft.jsch.Session session = null;
        try {
            JSch jsch = new JSch();
            session = jsch.getSession(username, host, port);
            session.setPassword(DESUtil.decrypt(password));
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.connect();
            Channel channel = session.openChannel("sftp");
            channel.connect();
            sftp = (ChannelSftp) channel;
            sftp.cd(servicePath);
            sftp.rm(fileName);
        } catch (JSchException | SftpException e) {
            System.out.println(e.getMessage());
        }finally {
            if (sftp != null) {
                if (sftp.isConnected()) {
                    sftp.disconnect();
                }
            }
            if (session != null) {
                if (session.isConnected()) {
                    session.disconnect();
                }
            }
        }
    }

    public static void upload(String host,int port,String username,String password,String serverPath, String localPath,String connectId){
        ChannelSftp sftp = null;
        com.jcraft.jsch.Session session = null;
        FileInputStream fileInputStream = null;
        try {
            JSch jsch = new JSch();
            session = jsch.getSession(username, host, port);
            session.setPassword(DESUtil.decrypt(password));
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.connect();
            Channel channel = session.openChannel("sftp");
            channel.connect();
            sftp = (ChannelSftp) channel;
            File file = new File(localPath);
            LogUtil.info("文件："+serverPath,connectId,host);
            fileInputStream = new FileInputStream(file);
            sftp.put(fileInputStream,serverPath);
        } catch (JSchException | FileNotFoundException | SftpException e) {
            e.printStackTrace();
        }finally {
            if (sftp != null) {
                if (sftp.isConnected()) {
                    sftp.disconnect();
                }
            }
            if (session != null) {
                if (session.isConnected()) {
                    session.disconnect();
                }
            }
            if (fileInputStream != null){
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    public static void batchUploadFile(String host,int port,String username,String password,Map<String,String> pathMap,String connectId){
        ChannelSftp sftp = null;
        com.jcraft.jsch.Session session = null;
        try {
            JSch jsch = new JSch();
            session = jsch.getSession(username, host, port);
            session.setPassword(DESUtil.decrypt(password));
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.connect();
            Channel channel = session.openChannel("sftp");
            channel.connect();
            sftp = (ChannelSftp) channel;
            for (Map.Entry<String, String> entry : pathMap.entrySet()) {
                LogUtil.info(entry.getValue(),connectId,host);
                try(FileInputStream fis = new FileInputStream(entry.getKey())) {
                    sftp.put(fis,entry.getValue());
                    System.gc();
                    File file = new File(entry.getKey());
                    file.delete();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        } catch (JSchException | SftpException e) {
            e.printStackTrace();
        }finally {
            if (sftp != null) {
                if (sftp.isConnected()) {
                    sftp.disconnect();
                }
            }
            if (session != null) {
                if (session.isConnected()) {
                    session.disconnect();
                }
            }
        }
    }

    public static final DeployPath deployPath = new DeployPath();

    public static void getDirectory(String localPath) {
        File file = new File(localPath);
        File[] listFiles = file.listFiles();
        if (listFiles == null || listFiles.length == 0) {
            return;
        }
        for (File f : listFiles) {
            if (f.isDirectory()) {
                getDirectory(f.getAbsolutePath());
            } else {
                deployPath.getDirList().add(f.getParent());
                deployPath.getFileList().add(f.getAbsolutePath());
            }
        }
    }

    public static void getDirectory(String localPath,String serverPath){
        for (String dir : deployPath.getDirList()) {
            String replace = dir.replace(localPath, "");
            String path = (serverPath+replace).replace("\\","/");
            path = path.replace(serverPath,"");
            path = path.equals("")?serverPath:path;
            if (serverPath.contains(path)){
                deployPath.setRootPath(path);
            }else {
                deployPath.getDirServerList().add(path.replaceAll("/",""));
            }
        }
        for (String path : deployPath.getFileList()) {
            String replace = path.replace(localPath, "");
            deployPath.getUploadMap().put(path,(serverPath+replace).replace("\\","/"));
        }
    }



}
